"""Flowable 流程部署 API"""
from __future__ import annotations

import os
import tempfile

from flask import request
from flask_restful import Resource

from ..utils.flowable_client import FlowableClient
from ..utils.helpers import success_response, error_response, handle_errors
from ..utils.process_definition_sync import parse_bpmn_process_tasks, sync_process_task_definitions
try:
    from server.config.config import Config  # type: ignore
except ModuleNotFoundError:
    from config.config import Config  # type: ignore


def _decode_bpmn_bytes(data: bytes) -> str:
    """尽可能以 UTF-8 解码 BPMN 字节内容。"""
    try:
        return data.decode('utf-8')
    except UnicodeDecodeError:
        try:
            return data.decode('utf-8-sig')
        except UnicodeDecodeError:
            return data.decode('latin-1', errors='ignore')


class FlowableDeploymentResource(Resource):
    """上传 BPMN 并部署到 Flowable，同时同步节点定义。"""

    def __init__(self):
        self.client = FlowableClient(
            base_url=Config.FLOWABLE_REST_URL,
            username=Config.FLOWABLE_REST_USER,
            password=Config.FLOWABLE_REST_PASSWORD
        )

    @handle_errors
    def post(self):
        if 'file' not in request.files:
            return error_response('缺少 BPMN 文件', 400)

        upload = request.files['file']
        if not upload.filename:
            return error_response('文件名缺失', 400)

        file_bytes = upload.read()
        if not file_bytes:
            return error_response('文件内容为空', 400)

        deployment_name = request.form.get('deploymentName') or request.form.get('name') or upload.filename
        suffix = os.path.splitext(upload.filename)[1] or '.bpmn20.xml'
        resource_name = os.path.basename(upload.filename) if upload.filename else ''

        with tempfile.NamedTemporaryFile(delete=False, suffix=suffix) as tmp:
            tmp.write(file_bytes)
            tmp_path = tmp.name


        print(f"部署流程: {deployment_name} from {upload.filename}")
        try:
            deploy_result = self.client.deploy_process(
                tmp_path,
                deployment_name=deployment_name,
                resource_name=resource_name
            )
            deployment_id = deploy_result.get('id')
            print(f"部署成功，部署ID: {deployment_id}")
            definitions = self.client.get_process_definitions_by_deployment(deployment_id) if deployment_id else []

            saved_count = 0
            if definitions:
                xml_text = _decode_bpmn_bytes(file_bytes)
                definitions_by_key = parse_bpmn_process_tasks(xml_text)
                key_to_id = {d.get('key'): d.get('id') for d in definitions if d.get('key') and d.get('id')}
                if key_to_id:
                    print(f"同步流程任务定义，数量: {len(definitions_by_key)}")
                    saved_count = sync_process_task_definitions(definitions_by_key, key_to_id)

            payload = {
                'deployment': deploy_result,
                'definitions': definitions,
                'tasks_saved': saved_count
            }
            return success_response(payload, '流程部署成功')
        finally:
            try:
                os.unlink(tmp_path)
            except OSError:
                pass
